package com.bnd.common.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.bnd.common.ErrorCode;
import com.bnd.common.holder.VoiceIdHolder;
import com.bnd.config.AiConfig;
import com.bnd.domain.CharacterInfo;
import com.bnd.domain.ChatHistory;
import com.bnd.domain.session.BaseChatSession;
import com.bnd.service.CharacterInfoService;
import com.bnd.service.ChatHistoryService;
import com.bnd.utils.MessageChatHistoryConverter;
import com.bnd.utils.ThrowUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

@Slf4j
public class GenericChatSessionManager<T extends BaseChatSession> {

    private final Map<Long, T> sessionMap = new ConcurrentHashMap<>();

    private final CharacterInfoService characterInfoService;
    private final ChatHistoryService chatHistoryService;
    private final AiConfig aiConfig;

    public GenericChatSessionManager(CharacterInfoService characterInfoService,
                                     ChatHistoryService chatHistoryService,
                                     AiConfig aiConfig) {
        this.characterInfoService = characterInfoService;
        this.chatHistoryService = chatHistoryService;
        this.aiConfig = aiConfig;
    }

    public T getOrCreate(String chatId, Long characterId, Function<String, T> sessionCreator) {
        return sessionMap.computeIfAbsent(characterId, k -> {
            T chatSession = sessionCreator.apply(chatId);
            List<Message> messageList = chatSession.getMessageList();

            //1. 参数校验
            CharacterInfo characterInfo = characterInfoService.getById(characterId);
            ThrowUtils.throwIf(characterInfo == null, ErrorCode.NOT_FOUND_ERROR, "角色不存在，ID: " + characterId);
            ThrowUtils.throwIf(StrUtil.isBlank(characterInfo.getPrompt()),
                    ErrorCode.SYSTEM_ERROR, "角色提示词为空，角色名: " + characterInfo.getName());

            //2. 校验音色ID是否合法
            String voiceId = characterInfo.getVoice();
            // 如果音色ID不合法，则使用默认的音色ID
            voiceId = VoiceIdHolder.isValidVoiceId(voiceId) ? voiceId : aiConfig.getDashscope().getSsVoice();
            chatSession.setVoiceId(voiceId);

            //3. 加载角色系统提示词
            messageList.add(Message.builder()
                    .role(Role.SYSTEM.getValue())
                    .content(characterInfo.getPrompt())
                    .build());

            //4. 加载历史聊天记录
            List<ChatHistory> historyList = chatHistoryService.listByCharacterId(characterId);
            if (CollectionUtil.isNotEmpty(historyList)) {
                List<Message> historyMessages = MessageChatHistoryConverter.chatHistoryListToMessageList(historyList);
                messageList.addAll(historyMessages);
            }

            return chatSession;
        });
    }

    public T remove(Long characterId) {
        T removed = sessionMap.remove(characterId);
        if (removed != null) {
            log.info("【GenericChatSessionManager】会话已移除: characterId={}", characterId);
        }
        return removed;
    }

    public void clearAll() {
        int size = sessionMap.size();
        sessionMap.clear();
        log.info("【GenericChatSessionManager】已清除全部会话，共 {} 个", size);
    }

    public int getSessionCount() {
        return sessionMap.size();
    }

    public boolean containsSession(Long characterId) {
        return sessionMap.containsKey(characterId);
    }
}
